<template>
  <div class="product-list-container list-container" v-loading.fullscreen.lock="loading" >
    <div id="product-product-list"></div>
    <div ref="tableHeaderContainer" class="product-list-search-group-container bg-w list-search-group-container" style="display:block;">
      <!-- 搜索 -->
      <div class="task-list-header-search" style="align-items:center;">
        <div class="left-filter-box">
          <!-- 视图列表 -->
          <viewport-dropdown ref="viewportListRef" module="product" :current-view="currentView" @choose="chooseView" @edit="editViewByViewport" @create="editViewByViewport" :preViews="preViews"></viewport-dropdown>
          <!-- 视图编辑弹框 -->
          <advanced-search-modal ref="advancedSearchModalRef" module="product" :fields="searchFieldInfo" @save="handleViewportSave">
          </advanced-search-modal>
        </div>

        <form class="task-flex task-ai " onsubmit="return false;">
          <div class="task-flex">
            <!--              :placeholder="$t('product.list.placeholder.quickSearch1')"-->
            <el-input v-model="searchModel.keyword"
                      :placeholder=" searchModel.searchCondition === '' ? $t('product.list.placeholder.quickSearch1') : t('task.model.tip.searchTaskTip3') "
                      class="task-select-search-input input-with-append-search task-mr12">
              <!--              <i slot="prefix" class="el-input__icon el-icon-search"></i>-->
              <el-select
                v-model="searchModel.searchCondition"
                slot="prepend"
                :placeholder="$t('common.placeholder.select')"
                class="task-with-select"
              >
                <el-option :label="$t('task.list.formContent')" value=""></el-option>
                <el-option :label="$t('task.record.taskCard')" value="ADDITIONAL"></el-option>
              </el-select>

              <el-button
                type="primary"
                slot="append"
                @click="searchModel.pageNum = 1; search(); trackEventHandler('search');"
                v-track="$track.formatParams('KEYWORD_SEARCH')"
                native-type="submit">
                {{$t('common.base.search')}}
              </el-button>
            </el-input>
            <el-button type="plain-third" @click="resetParams" v-track="$track.formatParams('RESET_SEARCH')">{{$t('common.base.reset')}}</el-button>
          </div>
          <!-- 高级搜索 -->
          <div id="product-product-list-2"
               :class="['advanced-search-visible-btn', 'bg-w']">
            <advanced-search
              :fields="searchFieldInfo"
              :search-model="viewportSearchModel"
              :has-save="!!(currentView && currentView.viewId && currentView.authEdit)"
              :in-common-use="inCommonUse"
              module="product"
              @changeCommonUse="changeCommonUse"
              @search="handleAdvancedSearch"
              @create="createViewBySearchModel"
              @save="updateViewBySearchModel"
            />
          </div>
        </form>
      </div>
      <!-- <div>
        <el-radio-group v-model="searchModel.hasBindCustomer" @change="getBindList" v-if="productCreateUnBindCustomer" style="position: relative;top: 4px">
          <el-radio-button :label="-1">全部产品</el-radio-button>
          <el-radio-button :label="1">已关联客户</el-radio-button>
          <el-radio-button :label="0">未关联客户</el-radio-button>
        </el-radio-group>
      </div> -->
    </div>

    <div class="product-list-section list-section">
      <!--operation bar start-->
      <div ref="tableDoContainer" class="operation-bar-container">
        <div class="top-btn-group flex-x task-flex">

          <el-button type="primary" @click="goToCreate" v-if="createdPermission" v-track="$track.formatParams('TO_CREATE', 'PRODUCT_CREATE')">
            {{$t('common.base.create')}}
          </el-button>

          <!-- 智能计划 -->
          <el-button
            type="plain-third"
            @click="handleCommand('smartPlan')"
            v-if="isShowCreateSmartPlan"
          >
            {{ $t('smartPlan.title') }}
          </el-button>

          <!-- 触发器 -->
          <!-- TODO: 暂不显示 -->
          <!-- <el-button
            v-for="item in triggerButtonList"
            :key="item.id"
            type="plain-third"
            @click="handleCommand(item)"
          >
            {{ item.triggerName }}
          </el-button> -->

          <el-button type="plain-third" @click="openDialog('sendMessage')" v-if="editedPermission === 3 && bindCustomer && isShowSendSMS" v-track="$track.formatParams('SEND_MESSAGE')">
            {{$t('common.base.sendSMS')}}
          </el-button>

          <el-button type="plain-third" @click="openDialog('sendEmail')" v-if="isShowEmail" v-track="$track.formatParams('SEND_EMAIL')">
            {{$t('common.base.sendEmail')}}
          </el-button>

          <!-- 发送活动调研 -->
          <send-activity-research v-if="createdActivityPermission && isShowProductSendActivitySurvey" mode="PRODUCT" :selection="multipleSelection"></send-activity-research>

          <el-button type="primary" v-if="searchModel.hasBindCustomer==0 && showBindCustomer" @click="openDialog('bindCustomer')">
            {{$t('product.btns.relateCustomer')}}
          </el-button>

          <el-button type="plain-third" @click="openDialog('remind')" v-if="editedPermission === 3 && isShowCustomerRemind" v-track="$track.formatParams('BATCH_REMIND')">
            {{$t('common.base.batchRemind')}}
          </el-button>

          <el-button type="plain-third" @click="openDialog('edit')" v-if="editedPermission === 3" v-track="$track.formatParams('BATCH_EDIT')">
            {{$t('common.base.bulkEdit')}}
          </el-button>

          <el-button type="plain-third" @click="deleteProducts" v-if="deletePermission" v-track="$track.formatParams('DELETE')">
            {{$t('common.base.batchDelete')}}
          </el-button>

          <template v-if="pageButtonSetGray">
            <template v-for="(item, index) in pageButtonList">
              <el-button
                :type="item.viewType"
                @click="handlePageButtonClick(item)"
                :loading="[ButtonSetDetailForButtonConcatEventEnum.Trigger, ButtonSetDetailForButtonConcatEventEnum.Code].includes(item.event[0].type) && pageButtonLoading"
                >
                {{item.name}}
              </el-button>
            </template>
          </template>

          <!-- 批量操作（除新建以外的其它按钮） -->
          <el-dropdown
            v-if="isShowBatchOperation"
            :hide-on-click="false"
            trigger="click"
            @command="handleCommand"
          >
            <el-button type="plain-third">{{ $t('part.text40') }}</el-button>
            <el-dropdown-menu class="batch-operation-dropdown-menu" slot="dropdown">
              <!-- 新建智能计划 -->
              <el-dropdown-item v-if="isShowCreateSmartPlan" command="smartPlan">
                <div class="dropdown-name">{{ $t('smartPlan.title') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'smartPlan', {tile: smartPlanButtonTile})"
                >
                  <i class="iconfont" :class="[smartPlanButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 触发器 -->
              <el-dropdown-item v-for="item in triggerList" :key="item.id" :command="item">
                <div class="dropdown-name">{{ item.triggerName }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, item.id, {tile: getButtonTile(item.id)})"
                >
                  <i class="iconfont" :class="[getButtonTile(item.id) ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 发送短信 -->
              <el-dropdown-item v-if="editedPermission === 3 && bindCustomer && isShowSendSMS" command="sendMessage">
                <div class="dropdown-name">{{ $t('common.base.sendSMS') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'sendMessage', {tile: sendMessageButtonTile})"
                >
                  <i class="iconfont" :class="[sendMessageButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 发送邮件 -->
              <el-dropdown-item v-if="isShowEmail" command="sendEmail">
                <div class="dropdown-name">{{ $t('common.base.sendEmail') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'sendEmail', {tile: sendEmailButtonTile})"
                >
                  <i class="iconfont" :class="[sendEmailButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 发送活动调研 -->
              <el-dropdown-item v-if="createdActivityPermission && isShowProductSendActivitySurvey" command="sendActivity">
                <div class="dropdown-name">
                  <send-activity-research ref="sendActivityResearch" mode="PRODUCT" :selection="multipleSelection">
                    {{ $t('customer.sendActivitySurvey') }}
                  </send-activity-research>
                </div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'sendActivity', {tile: sendActivityButtonTile})"
                >
                  <i class="iconfont" :class="[sendActivityButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 关联客户 -->
              <el-dropdown-item v-if="searchModel.hasBindCustomer == 0 && showBindCustomer" command="bindCustomer">
                <div class="dropdown-name">{{ $t('product.btns.relateCustomer') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'bindCustomer', {tile: bindCustomerButtonTile})"
                >
                  <i class="iconfont" :class="[bindCustomerButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 添加提醒 -->
              <el-dropdown-item v-if="editedPermission === 3 && isShowCustomerRemind" command="remind">
                <div class="dropdown-name">{{ $t('common.base.batchRemind') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'remind', {tile: remindButtonTile})"
                >
                  <i class="iconfont" :class="[remindButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 批量编辑 -->
              <el-dropdown-item v-if="editedPermission === 3" command="edit">
                <div class="dropdown-name">{{ $t('common.base.bulkEdit') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'edit', {tile: editButtonTile})"
                >
                  <i class="iconfont" :class="[editButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 删除 -->
              <el-dropdown-item v-if="deletePermission" command="delete">
                <div class="dropdown-name">{{ $t('common.base.batchDelete') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'delete', {tile: deleteButtonTile})"
                >
                  <i class="iconfont" :class="[deleteButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>

        <div class="action-button-group bg-w" id="product-product-list-3">
          <!-- start 客户标签筛选 -->
          <template v-if="isBgiPrivate">
            <biz-customer-tag-select @change="searchCustomerTags" />
          </template>
          <!-- end 客户标签筛选 -->
          <el-dropdown trigger="click" v-if="exportPermission">
            <div class="task-ai task-font14 task-c6 cur-point bg-w"
                 @click="trackEventHandler('moreAction')">
              <span class="task-mr4 task-ml4">{{$t('common.base.moreOperator')}}</span>
              <i class="iconfont icon-fdn-select"></i>
            </div>
            <el-dropdown-menu slot="dropdown">

              <el-dropdown-item v-if="!isExperienceEdition && isButtonDisplayed && canProductImport">
                <div @click="openDialog('importProduct')" v-track="$track.formatParams('IMPORT_PRODUCT', null, 'MORE_ACTIONS')">{{$t('common.base.importProduct')}}</div>
              </el-dropdown-item>

              <!--   导入附加组件     -->
              <el-dropdown-item v-if="showBatchImportAddOnBtn">
                <div class="import-product">
                  {{$t('component.batchImportAddOnModal.title1')}}
                  <div class="import-product-item import-item">
                    <div
                      v-for="(item, index) in enabledCardList"
                      :key="`${index}_${item.cardId}`"
                      @click="toImportProduct(item.cardId)"
                    >
                      {{ item.cardName }}
                    </div>
                  </div>
                </div>
              </el-dropdown-item>

              <el-dropdown-item v-if="isButtonDisplayed && canProductExport">
                <div @click="exportProduct(false)" v-track="$track.formatParams('EXPORT', null, 'MORE_ACTIONS')">{{$t('common.base.export')}}</div>
              </el-dropdown-item>

              <el-dropdown-item v-if="isButtonDisplayed && canProductExport">
                <div @click="exportProduct(true)" v-track="$track.formatParams('EXPORT_ALL', null, 'MORE_ACTIONS')">{{$t('common.base.exportAll')}}</div>
              </el-dropdown-item>
              <el-dropdown-item v-if="!isExperienceEdition && canProductImport">
                <div @click="openDialog('update')" v-track="$track.formatParams('BATCH_UPDATE', null, 'MORE_ACTIONS')">{{$t('common.base.batchUpdate')}}</div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
          <!-- 选择列 -->
          <div class="guide-box">
            <div :class="[
                   'task-ai',
                   'task-font14',
                   'task-c6',
                   'cur-point',
                   'task-width103',
                 ]"
                v-track="$track.formatParams('SELECT_COLUMN')"
                @click="showAdvancedSetting">
              <span class="task-mr4">{{$t('common.base.choiceCol')}}</span>
              <i class="iconfont icon-fdn-select"></i>
            </div>
          </div>
        </div>
      </div>

      <div id="product-product-list-1" class="bg-w pad-l-16 pad-r-16">
        <el-table
          stripe
          :data="page.list"
                     :highlight-current-row="false"
                     :key="tableKey"
                     :row-key="getRowKey"
                     :border="true"
                     @select="handleSelection"
                     @select-all="handleSelection"
                     @sort-change="sortChange"
                     @header-dragend="headerDragend"
                     :class="['task-list-table', 'common-list-table', 'bg-w', 'bbx-normal-list-box']"
                     header-row-class-name="common-list-table-header taks-list-table-header"
                     :height="tableContainerHeight"
                     ref="multipleTable">
          <template slot="empty">
            <BaseListForNoData v-show="!loading" :notice-msg="$t('common.base.tip.noData')"></BaseListForNoData>
          </template>
          <el-table-column type="selection"
                              align="center"
          ></el-table-column>
          <template v-for="(column, index) in columns">
            <el-table-column v-if="column.show"
                                :key="`${column.field}_${index}`"
                                :label="column.label"
                                :prop="column.field"
                                :width="column.width"
                                :min-width="column.minWidth || '120px'"
                                :sortable="column.sortable"
                                :show-overflow-tooltip="getProductListShowTooltip(column)"
                                :fixed="column.fixLeft || false"
                                :align="column.align">
              <template slot-scope="scope">
                <template v-if="column.field === 'name'">
                  <sample-tooltip :row="scope.row">
                    <template slot="content" slot-scope="{ isContentTooltip }">
                      <el-tooltip :content="scope.row[column.field]"
                                     placement="top-start"
                                     :disabled="!isContentTooltip">
                        <div
                          :class="globalIsHaveProductViewDetailAuth ? 'view-detail-btn' : 'view-detail-btn-disabled'"
                          @click.stop.prevent="openProductTab(scope.row.id)"
                        >
                          {{ scope.row[column.field] }}
                        </div>
                      </el-tooltip>
                    </template>
                  </sample-tooltip>
                </template>
                <template v-else-if="column.fieldName == 'productDesc'">
                  {{ scope.row[column.field] }}
                </template>
                <template v-else-if="column.formType === 'connector'">
                  <div v-if="scope.row.attribute && scope.row.attribute[column.field]" class="view-detail-btn task-client" @click.stop="openConnectorDialog(column, scope.row)">
                    {{ $t('common.base.view') }}
                  </div>
                </template>
                <!-- 是否重复报修 -->
                <template v-else-if="column.field === 'isRepeatRepair'">
                  <span :style="{color: column.setting.color || '#F4882F'}">{{scope.row.attribute[column.field] || $t('common.base.no')}}</span>
                </template>
                <template v-else-if="column.field === 'customer' && scope.row.customer">
                  <a href=""
                     class="view-detail-btn"
                     v-if="scope.row.customer.name"
                     @click.stop.prevent="createCustomerTab(scope.row.customer.id)">
                    {{ scope.row.customer.name}}
                  </a>
                  <span v-else class="unbind">{{$t('common.base.notContact')}}</span>
                </template>
                <template v-else-if="column.field === 'productTemplate'">
                  <a href=""
                     class="view-detail-btn"
                     @click.stop.prevent="createTemplateTab(scope.row.templateId)">
                    {{ scope.row.templateName }}
                  </a>
                </template>
                <template v-else-if="column.field === 'tags'">
                  {{ scope.row | formatTags }}
                </template>
                <!-- 自定义的选择类型字段显示， 与type 区别-->
                <template v-else-if="column.formType === 'cascader'">
                  <!-- 这里区分下自定义字段 -->
                  <template v-if="!column.isSystem">
                    {{ $formatFormField(column, scope.row) }}
                  </template>
                  <template v-else>
                    {{ scope.row[column.field] | displaySelect }}
                  </template>
                </template>
                <template v-else-if="column.formType === 'select' && !column.isSystem">
                   <!-- 下拉菜单标签模式 -->
                  <template v-if="column.setting.selectType == 3">
                    <TagsModeSelect :field="column" :value="scope.row.attribute[column.field]" />
                  </template>
                  <template v-else>
                    {{ scope.row.attribute[column.field] | displaySelect }}
                  </template>
                </template>
                <template v-else-if="column.field === 'updateTime'">
                  <template v-if="scope.row.latesetUpdateRecord && !isOpenData">
                    <el-tooltip class="item"
                                   effect="dark"
                                   placement="top-start"
                                   :content="scope.row.latesetUpdateRecord">

                      <div @mouseover="showLatestUpdateRecord(scope.row)">
                        {{ scope.row.updateTime | formatDate }}
                      </div>
                    </el-tooltip>
                  </template>
                  <template v-else>
                    <div @mouseover="showLatestUpdateRecord(scope.row)">
                      {{ scope.row.updateTime | formatDate }}
                    </div>
                  </template>
                </template>
                <template v-else-if="column.fieldName === 'productCompleteAddress'">
                  {{ scope.row['productCompleteAddress'] }}
                </template>
                <template v-else-if="column.formType === 'address'">
                  {{ formatCustomizeAddress(scope.row.attribute[column.field]) }}
                </template>
                <template v-else-if="
                  column.formType === 'user' &&
                    scope.row.attribute[column.field]
                ">
                  <template v-if="isOpenData">
                    <open-data v-for="staffId in getUserIds(scope.row.attribute[column.field])" :key="staffId" type="userName" :openid="staffId"></open-data>
                  </template>
                  <template v-else>
                    {{ getUserName(column, scope.row.attribute[column.field]) }}
                  </template>

                </template>
                <template v-else-if="column.formType === 'location'">
                  {{
                    scope.row.attribute[column.field] &&
                      scope.row.attribute[column.field].address
                  }}
                </template>
                <template v-else-if="column.formType == 'related_task'">
                  {{ getRelatedTask(scope.row.attribute[column.field]) }}
                </template>
                <!-- 服务商 -->
                <template v-else-if="column.formType == 'serviceProviders'">
                    {{ scope.row.serviceProviderSubForm | serviceProviderColumnValue }}
                </template>

                <template v-else-if="column.formType === 'logistics'">
                  <biz-list-logistics-no
                    :row="scope.row"
                    :column="column"
                    :is-link="isCanLogisticsNoLink(column)"
                    mode="product"
                    :biz-id="scope.row.id"
                  />
                </template>

                <template v-else-if="column.field === 'createUser'">
                  <template v-if="isOpenData && scope.row.createUser">
                    <open-data type='userName' :openid="scope.row.createUser.staffId"></open-data>
                  </template>
                  <template v-else>
                    {{ scope.row.createUser && scope.row.createUser.displayName }}
                  </template>
                </template>
                <template v-else-if="column.field === 'createTime'">
                  {{ scope.row.createTime | formatDate }}
                </template>
                <div v-else-if="column.formType === 'textarea'"
                     v-html="buildTextarea(scope.row.attribute[column.field])"
                     @click="openOutsideLink"></div>

                <template v-else-if="column.fieldName == 'linkmanName'">
                  {{ scope.row.linkman.name }}
                </template>

                <template v-else-if="column.fieldName == 'phone'">
                  {{ scope.row.linkman.phone }}
                </template>

                <template v-else-if="column.fieldName == 'address'">
                  {{ formatCustomizeAddress(scope.row.address) }}
                </template>

                <!-- 富文本 -->
                <template v-else-if="column.formType === 'richtext'">
                  <div class='view-detail-btn' @click.stop="openRichtextVisible(scope.row, column)">
                    <span v-if="scope.row.attribute && scope.row.attribute[column.field]">{{$t('common.base.view')}}</span>
                  </div>
                </template>



                <!-- TODO: 中文判断，需要确认有没有问题 -->
                <template v-else-if="column.label=='购买日期' || column.label=='过保日期'">
                  {{ scope.row.attribute[column.field] | formatDate2 }}
                </template>
                <!-- 客户标签 -->
                <template v-else-if="column.field == 'customerTag'">
                  <div :style="{paddingTop: '10px'}">
                    <el-tooltip class="item" effect="dark" placement="top">
                      <div slot="content">
                        {{  scope.row.customer.esTenantTagList | serviceProviderColumnValue }}
                      </div>
                      <base-tags :value="customerLabel(scope.row.customer.esTenantTagList)" />
                    </el-tooltip>
                  </div>
                </template>
                <template v-else-if="!column.isSystem">
                  {{ $formatFormField(column, scope.row) }}
                </template>

                <!-- 移植自产品类型列表并同步更新 s -->
                <!-- 标准版取字段有问题，先简单改下，后续理清楚~ -->
                <!-- 服务云项目去掉产品类型字段示例数据显示 -->
                <template v-else-if="['catalogId', 'pathName'].includes(column.fieldName)">
                  <template v-if="scope.row['pathName'] && isOpenSuperCodePro">
                    <a href="" v-if="productTypePermission" class="view-detail-btn"
                        @click.stop.prevent="openProductMenuTab(scope.row.catalogId)">
                      {{ (scope.row['pathName'] && scope.row['pathName'].replace(new RegExp("/","g") ,' / ')) || '' }}
                    </a>
                    <span v-else> {{ (scope.row['pathName'] && scope.row['pathName'].replace(new RegExp("/","g") ,' / ')) || '' }}</span>
                  </template>
                  <template v-if="scope.row['pathName'] && !isOpenSuperCodePro">
                    <span> {{ scope.row['type'] || '' }} </span>
                  </template>
                </template>

                <template v-else-if="column.fieldName === 'productPic'">
                  <div v-if="scope.row.productPic"
                       class="flex-x goods-img-list"
                       style="height:100%">
                    <template v-for="(item, index) in scope.row.productPic">
                      <img :key="index"
                           v-if="index <= 4"
                           class="cur-point"
                           :src="
                             item.url
                               ? `${item.url}?x-oss-process=image/resize,m_fill,h_32,w_32`
                               : defaultImg
                           "
                           @click.stop="previewImg(item.url,scope.row.productPic)" />
                    </template>
                    <div>
                      {{
                        scope.row[column.field].length > 5
                          ? `+${scope.row[column.field].length - 5}`
                          : ''
                      }}
                    </div>
                  </div>
                </template>

                <template v-else-if="column.fieldName === 'productVideo'">
                  <template v-if="scope.row.productVideo">
                    <sample-tooltip :row="scope.row">
                      <template slot="content" slot-scope="{ isContentTooltip }">
                        <a
                          href=""
                          class="view-detail-btn"
                          @click.stop.prevent="previewVideo(scope.row.productVideo[0].url)"
                        >
                          {{
                            scope.row.productVideo[0] &&
                              scope.row.productVideo[0].filename
                          }}
                        </a>
                      </template>
                    </sample-tooltip>
                  </template>
                </template>

                <!-- 移植自产品类型列表并同步更新 e -->
                <template v-else-if="column.fieldName === 'qrcodeId'">
                  <el-button v-if="canProductCodeProduct" @click="bindCode(scope.row)" type="text">{{scope.row[column.field] || $t('common.base.contact2')}}</el-button>
                  <template v-else>{{scope.row[column.field] || ''}}</template>
                </template>

                <template v-else-if="column.field === 'productStatus'">
                  <el-switch
                    :disabled="scope.row.pending"
                    @change="toggleStatus(scope.row)"
                    v-model="scope.row.productStatus"
                  ></el-switch>
                </template>

                <template v-else-if="column.field === 'productManager'">
                  <template v-if="isOpenData">
                    <open-data type='userName' :openid="scope.row.productManagerStaffId"></open-data>
                  </template>
                  <template v-else>
                    {{scope.row.productManagerName}}
                  </template>
                </template>

                <template v-else>
                  {{ $formatFormField(column, scope.row) }}
                </template>

              </template>
            </el-table-column>
          </template>
        </el-table>
      </div>

      <div ref="tableFooterContainer" class="table-footer bbx-normal-table-footer-10">
        <div class="list-info">
          <i18n path="common.base.table.totalCount">
            <span place="count" class="level-padding">{{page.totalElements}}</span>
          </i18n>
          <template v-if="multipleSelection&&multipleSelection.length>0">
            <i18n path="common.base.table.selectedNth">
              <span
                place="count"
                class="product-selected-count"
                @click="multipleSelectionPanelShow = true"
              >{{multipleSelection.length}}</span>
            </i18n>
            <span class="product-selected-count" @click="toggleSelection()">{{$t('common.base.clear')}}</span>
          </template>
        </div>
        <el-pagination class="product-table-pagination"
                          background
                          @current-change="jump"
                          @size-change="handleSizeChange"
                          :page-sizes="defaultTableData.defaultPageSizes"
                          :page-size="searchModel.pageSize"
                          :current-page="searchModel.pageNum"
                          layout="prev, pager, next, sizes, jumper"
                          :total="page.totalElements">
        </el-pagination>
      </div>
    </div>

    <base-panel class="product-panel"
                :show.sync="multipleSelectionPanelShow"
                width="420px">
      <h3 slot="title">
        <span>{{$t('product.list.chosenProducts')}}({{ multipleSelection.length }})</span>
        <i v-if="multipleSelection.length"
           class="iconfont icon-qingkongshanchu product-panel-btn"
           @click="toggleSelection()"
           title="$t('common.base.tip.clearChoseDataTip')"
           data-placement="right"
           v-tooltip></i>
      </h3>

      <div class="product-selected-panel">
        <div class="product-selected-tip"
             v-if="!multipleSelection.length">
          <img :src="noDataImage" />
          <p>{{$t('product.list.selectedPanel.noData')}}</p>
        </div>
        <template v-else>
          <div class="product-selected-list">
            <div class="product-selected-row product-selected-head">
              <span class="product-selected-name">{{ $t('common.base.product') }}</span>
            </div>
            <div class="product-selected-row"
                 v-for="c in multipleSelection"
                 :key="c.id">
              <span class="product-selected-sn">{{ c.name }}</span>
              <button type="button"
                      class="product-selected-delete"
                      @click="removeFromSelection(c)">
                <i class="iconfont icon-fe-close"></i>
              </button>
            </div>
          </div>
        </template>
      </div>
    </base-panel>

    <biz-send-message ref="messageDialog" mode="product" :type="'repeatPhone'" :selected-ids="selectedIds" :sms-rest="smsRest"></biz-send-message>

    <biz-send-email ref="emailDialog" :selected-ids="selectedIds" mode="PRODUCT"></biz-send-email>

    <batch-editing-dialog ref="batchEditingDialog"
                          :config="{ fields: onlyProductEditFields, productTypes: productTypes }"
                          :callback="search"
                          :selected-ids="selectedIds"
                          :select-list='multipleSelection'></batch-editing-dialog>

    <biz-batch-remind ref="batchRemindingDialog" modal="product" :has-bind-customer="bindCustomer" :selected-ids="selectedIds" ></biz-batch-remind>

    <base-import :title="$t('common.base.importProduct')"
                 ref="importProductModal"
                 @success="search"
                 :action="customerProductImportNew">
      <div slot="tip">
        <div class="base-import-warn">
          <p>
            <i18n path="common.base.importModal.downloadTemplateTip" tag="span">
              <a place="link" :href="customerProductImportNewTem">{{$t('common.base.importModal.importTemplate')}}</a>
            </i18n>
            <!-- 请先下载<a :href="customerProductImportNewTem">导入模版 </a>，填写完成后再上传导入。 -->
          </p>
        </div>
      </div>
    </base-import>
    <!-- start 产品导出 -->
    <base-export-group ref="exportPanel"
                       :storage-key="exportStorageKey"
                       :alert="exportAlert"
                       :columns="exportColumns"
                       :build-params="buildExportParams"
                       :group="true"
                       :validate="checkExportCount"
                       :needchoose-break="false"
                       method="post"
                       :action="productListExport"
                       :is-show-export-tip="isOpenData"/>
    <!-- end 产品导出 -->

    <biz-batch-update ref="batchUpdateDialog"
                      :selected-ids="selectedIds"
                      :total-items="page.totalElements"
                      :build-download-params="buildParams"
                      @success="search"
                      action="/excels/customer/customerProductUpdateBatchNew"></biz-batch-update>
    <biz-select-column ref="advanced" mode="product" :sotrage-key="'productV2_select_colum'" @save="saveColumnStatus" />


    <public-dialog
      :product-id="productId"
      dialog-type="linkQrcode"
      @dialogBind="dialogBind"
      ref="publicDialog" />

    <qrcode-dialog
      ref="qrcodeDialog"
      :init-data='initData'
      dialog-type="预览"
      :from-product='true'
      :qrcode-data='qrcodeData' />

    <customer-bind ref="customerBind" :fields='dynamicFields' :selected-ids="selectedIds" @refresh="refresh"></customer-bind>

    <!-- 连接器明细弹窗 -->
    <connector-table-dialog ref="connectorDialogRef" />
    <!-- 新建智能计划弹窗 -->
    <createSmartPlanDialog :products="multipleSelection" ref="createSmartPlanDialog" />
    <base-view-rich-text ref="baseViewRichTextRef"></base-view-rich-text>
    <!-- 产品保存 -->
    <base-save
    ref="productSaveRef"
    :has-save="!!(currentView && currentView.viewId && currentView.authEdit)"
    module="product"
    :current-view="currentView"
    @save="handleViewportSave"
    />


    <base-import
      :title="$t('component.batchImportAddOnModal.title1')"
      ref="importAddOnModal"
      :action="productAddOnsImportUrl"
      :template-url="productAddOnsImportTemplateUrl">
    </base-import>
  </div>
</template>

<script>
// pageDes 产品列表
import { isOpenData, openAccurateTab } from '@src/util/platform'
import _,{ cloneDeep }  from 'lodash';
import { safeNewDate } from '@src/util/time';
import { getSortableMinWidth, defaultTableData } from '@src/util/table';

import Page from '@model/Page';
import { checkButtonDisplayed, getRootWindow } from '@src/util/dom';
import BatchEditingDialog from '@src/modules/productV2/productList/compoment/BatchEditingDialog.vue';
import { storageGet, storageSet } from '@src/util/storageV2';
import PublicDialog from '@src/modules/productV2/productView/components/PublicDialog.vue';
import QrcodeDialog from '@src/modules/productV2/superQrcode/component/QrcodeDialog.vue';
import CustomerBind from '../productView/components/CustomerBind.vue';
import CustomizeFilterView from '@src/modules/customer/components/CustomizeFilterView/index.vue'
import SendActivityResearch from '@src/modules/customer/components/SendActivityResearch/index.vue'
import TagsModeSelect from 'src/component/form/common/components/RelationOptionsModal/TagsModeSelect/index.vue';
import PropagandaPage from '@src/component/compomentV2/PropagandaPage';
import { FieldTypeMappingEnum } from '@model/enum/FieldMappingEnum';
/* export & import */
import {
  customerProductImportNew,
  customerProductImportNewTem,
  productAddOnsImportTemplate,
  productAddOnsImport
} from '@src/api/Import';
import { productListExport } from '@src/api/Export';
import { formatDate, useFormTimezone } from 'pub-bbx-utils'
const { disposeFormListViewTime } = useFormTimezone()

import {
  getProductV2,
  deleteProductByIds,
  getUpdateRecord,
  updateProductStatus,
  getProductFields,
  bindQrcode
} from '@src/api/ProductApi';
import {
  getEnabledCardInfo
} from '@src/api/SettingCusProApi';
import * as CustomerApi from '@src/api/CustomerApi.ts';
import { fetchViewportList } from '@src/api/Viewport';

import { PRODUCT_LIST_LOCALSTORAGE_20_11_25 } from '@src/modules/productV2/storage.js'

import { catalogFieldFixForProduct, productFieldFix } from '@src/modules/productV2/public.js';
import { getProductLinkCatalogCount } from '@src/api/ProductV2Api'
import { formatFields, customerSystemFields } from './fields';
/* mixin */
import ThemeMixin from '@src/mixins/themeMixin/index.ts'
import VersionMixin from '@src/mixins/versionMixin/index.ts'
import TeamMixin from '@src/mixins/teamMixin'
import AuthMixin from '@src/mixins/authMixin'
import ConnectorMixin from '@src/mixins/connectorMixin'
import ManualTriggerMixin from '@src/mixins/manualTriggerMixin'
import LogisticsMixin from '@src/mixins/logisticsMixin'
import baseSaveShowHandle from '@src/mixins/baseSaveMixin'
/* service */
import { smoothQualityInfoFieldForTable } from '@service/QualityInfoService.ts'
import { isQualityInfoStartTimeField, isQualityInfoEndTimeField, isQualityInfoStatusField } from '@service/FieldService.ts'
import { filterProductSearchParamsInvalidProperty } from '@service/ProductService.ts'
import { formattedOpenDataTooltip } from '@service/OpenDataService.ts'
import { smoothLogisticsField } from '@service/LogisticsService'
/* enum*/
import { PageRoutesTypeEnum } from 'pub-bbx-global/pageType/dist/enum/PageRoutesEnum'
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
// AdvancedSearch
import AdvancedSearch from '@src/component/AdvancedSearch/index.vue'
import AdvancedSearchModal from '@src/component/AdvancedSearch/AdvancedSearchModal.vue'
import ViewportDropdown from '@src/component/ViewportDropdown/index.vue'
import { getSystemNormalSearchInputForLength } from '@model/utils/getSystemConfig.ts'

import { parse } from '@src/util/querystring';

import { PRODUCT_PRODUCT_LIST } from '@src/component/guide/productV2Store';
/* mixin */
import { VersionControlProductMixin } from '@src/mixins/versionControlMixin'
import { isNotUndefined } from '@src/util/type';

const link_reg = /((((https?|ftp?):(?:\/\/)?)(?:[-;:&=\+\$]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\?\+=&;:%!\/@.\w_]*)#?(?:[-\+=&;%!\?\/@.\w_]*))?)/g;

import { customerLabel } from '@src/modules/customer/util/customer.js'

import { getOssUrl } from '@src/util/assets'
import { setServerCach, getServerCach } from '@src/util/serverCach'
const noDataImage = getOssUrl('/no_data.png')
import { formatAddress } from 'pub-bbx-utils';
import { hasBSCEnterpriseEdition } from '@src/util/version'
import { havePageButtonSetGray } from '@src/util/grayInfo'
import { pageButtonClick, getPageButtonListForView } from '@src/component/compomentV2/buttonSet/common'
import { ButtonGetTriggerModuleEnum, ButtonSetDetailForShowPositionEnum, ButtonSetDetailForButtonConcatEventEnum } from 'pub-bbx-global/pageType/dist/enum/ButtonSetEnum'

export default {
  name: 'product-list',
  mixins: [
    TeamMixin,
    VersionMixin,
    ThemeMixin,
    AuthMixin,
    ConnectorMixin,
    ManualTriggerMixin,
    VersionControlProductMixin,
    LogisticsMixin,
    baseSaveShowHandle
  ],
  inject: ['initData'],
  data () {
    return {
      defaultTableData,
      noDataImage,
      exportStorageKey: StorageKeyEnum.ProductListExport,
      currentView: null,
      advancedSearchModalVisible: false,
      viewportSearchModel: [],

      isButtonDisplayed: checkButtonDisplayed(),
      buttonStorageModule: 'productList',
      buttonStorageKey: 'productListButtonData',
      isOpenData,
      multipleSelectionPanelShow: false,
      page: new Page(),
      columns: [],
      multipleSelection: [],
      columnNum: 1,
      loading: true,
      customerSelectedTagIdList: [],
      selectedLimit: 500,
      searchIncludeMoreConditions: false,
      searchModel: {
        searchCondition:'', //表单内容-附加组件
        hasBindCustomer:-1, // 是否关联客户
        keyword: '',
        pageSize: 10,
        pageNum: 1,
        orderDetail: {},
        catalogState: '',
        moreConditions: {
          conditions: [],
        },
      },

      dynamicFields: [],
      filterTeams: [],
      tableKey: (Math.random() * 1000) >> 2,
      selectColumnState: 'product_list_select',
      // 头部筛选列表 s
      selectList: [
        { name: this.$t('common.base.all'), key: '', value: '' },
        { name: this.$t('product.list.selectList.withProductType'), key: 'buildCatalogNum', value: 1 },
        { name: this.$t('product.list.selectList.withoutProductType'), key: 'unBuildCatalogNum', value: 0 }
      ],
      selectCount: null,
      navWidth: window.innerWidth - 120,
      selectId: '',
      productId:'',
      qrcodeData:{},
      // 头部筛选列表 e
      productListExport,
      customerProductImportNew,
      customerProductImportNewTem,
      productAddOnsImportTemplateUrl: '',
      productAddOnsImportUrl: '',
      enabledCardList: [],
      filterViewModel: 'PRODUCT',
      tableContainerHeight:'440px',
      hasBindCustomerText: this.$t('product.list.allProduct'),
      preViews:[],
      inCommonUse: [], // 常用条件
      tableData: [],
      pageButtonSetGray:havePageButtonSetGray(),
      pageButtonList:[],
      pageButtonLoading:false,
      ButtonSetDetailForButtonConcatEventEnum
    };
  },
  computed: {
    // 是否显示导入附加组件按钮
    showBatchImportAddOnBtn() {
      return !!this.enabledCardList?.length
    },
    showBindCustomer(){
      return this.initData?.loginUser?.authorities?.PRODUCT_EDIT && this.initData?.productConfig?.productCreateUnBindCustomer
    },
    auth () {
      return (
        this.initData?.loginUser?.authorities || this.initData?.authorities
      );
    },
    isOpenSuperCodePro(){
      return this.initData?.openSuperCodePro
    },
    bindCustomer(){
      return this.searchModel.hasBindCustomer === 1 || this.searchModel.hasBindCustomer === -1
    },
    productCreateUnBindCustomer(){
      return this.initData?.productConfig?.productCreateUnBindCustomer
    },
    // 产品目录是否分列展示
    productMenuSplit() {
      return this.initData?.tenantConfig?.productMenuSplit
    },
    productTypePermission(){
      return this.auth?.PRODUCT_CATALOG_VIEW
    },
    editedPermission () {
      return this.auth?.PRODUCT_EDIT;
    },
    createdPermission () {
      return this.auth?.PRODUCT_CREATE;
    },
    viewedPermission () {
      return this.auth?.CUSTOMER_VIEW === 3;
    },
    deletePermission () {
      return this.auth?.PRODUCT_EDIT === 3 && this.auth?.PRODUCT_DELETE;
    },
    exportPermission () {
      return this.canProductImport || this.canProductExport
    },
    canProductImport() {
      return this.auth?.PRODUCT_IMPORT && this.createdPermission
    },
    canProductExport() {
      return this.auth?.PRODUCT_EXPORT
    },
    canProductCodeProduct() {
      return this.auth?.PRODUCT_CODE_PRODUCT
    },
    productFields () {
      let fixedFields = _.cloneDeep(productFieldFix);
      // 服务云企业版产品列表隐藏产品模版字段
      if(hasBSCEnterpriseEdition()) {
        fixedFields = fixedFields.filter(item=> item.fieldName != 'productTemplate')
      }
      // 是否启用产品超级二维码功能
      if (this.initData.productConfig.qrcodeEnabled && (this._isShowProductSuperQrcode || this._isShowProductQrcode)) {

        const placeholder = this._isShowProductSuperQrcode ? this.$t('product.placeholder.superQrcodeId') : this.$t('product.placeholder.qrcodeId')

        fixedFields.push({
          displayName: this.$t('product.type.qrcodeId'),
          fieldName: 'qrcodeId',
          formType: 'text',
          export: false,
          isSystem: 1,
          placeholder,
          orderId: 10001,
          tableName: 'product',
        });
      }

      // 是否开启产品目录分列展示
      if (this.productMenuSplit) {
        fixedFields.push({
          displayName: this.$t('common.base.productMenu'),
          fieldName: 'productMenu',
          formType: 'productMenu',
          export: true,
          isSystem: 1,
          orderId: this.dynamicFields.find(f => f.fieldName == 'catalogId')?.orderId - 1,
          tableName: 'product',
          setting: {},
        });
      }

      let field = this.dynamicFields.filter(
        (item) => item.formType == 'customer'
      )[0];
      if (field && field.setting.customerOption?.linkman) {
        fixedFields.push({
          displayName: this.$t('product.type.linkmanName'),
          fieldName: 'linkmanName',
          formType: 'text',
          export: true,
          isSystem: 1,
          tableName: 'product',
        });

        fixedFields.push({
          displayName: this.$t('common.form.type.phone'),
          fieldName: 'phone',
          export: true,
          isSystem: 1,
          tableName: 'product',
        });
      }

      if (field && field.setting.customerOption?.address) {
        fixedFields.push({
          displayName: this.$t('common.form.type.customerAddress'),
          fieldName: 'address',
          export: true,
          formType: 'text',
          isSystem: 1,
          tableName: 'product',
        });
      }

      // .concat([...fixedFields, ...catalogFieldFixForProduct])
      let fields = this.dynamicFields.concat([...fixedFields])
        .filter(
          (f) =>
            f.formType !== 'separator'
            && f.formType !== 'info'
            && f.formType !== 'autograph'
        ).filter(f => {

          const fieldNameShowMap = {
            hasRemind: this._isShowProductRemind,
            remindCount: this._isShowProductRemind,
            qrcodeState: this._isShowProductSuperQrcode,
            // catalogId: this._isShowProductType,
            productTemplate: this._isShowProductTemplate,
            qualityInfo: this._isShowProductQuality,
            qualityStartTime: this._isShowProductQuality,
            qualityEndTime: this._isShowProductQuality,
          }

          const isShow = fieldNameShowMap[f?.fieldName]
          if (isNotUndefined(isShow)) {
            return isShow
          }

          return f
        })
        .map((f) => {
          // 调整字段顺序
          if (f.fieldName === 'name') {
            f.orderId = -14;
            f.show = true;
          }

          // 新增产品是否重复报修自定义字段 放在产品名称后面
          if (f.fieldName === 'isRepeatRepair') {
            f.orderId = -13;
            f.show = true;
          }

          if (f.fieldName === 'customer') {
            f.orderId = -12;
            f.show = true;
          }

          if (f.fieldName === 'linkmanName') {
            f.orderId = -11;
            f.show = true;
          }

          if (f.fieldName === 'phone') {
            f.orderId = -10;
            f.show = true;
          }

          if (f.fieldName === 'address') {
            f.orderId = -9;
            f.show = true;
          }

          if (f.fieldName === 'serialNumber') {
            f.orderId = -6;
            f.show = true;
          }

          if (f.fieldName === 'type') {
            f.orderId = -5;
            f.show = true;
          }

          if (f.fieldName === 'tags') {
            f.orderId = -8;
          }

          if (f.fieldName === 'productTemplate') {
            f.orderId = -7;
          }

          if (f.fieldName === 'remindCount') {
            f.orderId = -3;
          }

          if (f.fieldName === 'updateTime') {
            f.orderId = -2;
          }

          if (f.fieldName === 'createUser') {
            f.orderId = -1;
            f.show = true;
          }

          if (f.fieldName === 'createTime') {
            f.orderId = 0;
            f.show = true;
          }
          if (f.fieldName === 'catalogId' && f.tableName == 'product') {
            // 转换产品类型表单数据
            if (!this.dynamicFields.some(f => f.fieldName === 'pathName')) {
              f.fieldName = 'pathName'
            }
          }

          // 系统字段默认显示
          f['show'] = f.isSystem ? true : f.show

          return f;
        })
        .sort((a, b) => a.orderId - b.orderId);

      return smoothQualityInfoFieldForTable(fields)
    },
    onlyProductEditFields() {
      return (
        this.onlyProductFields
          .filter(item => !isQualityInfoStatusField(item))
          .filter(item => item.fieldName != 'productMenu')
          .filter(item => item.formType !== 'logistics')
          .filter(item => item.formType !== FieldTypeMappingEnum.JsCodeBlock)
      )
    },
    onlyProductFields () {
      return (
        this.productFields
          .filter(item => item.tableName == 'product')
          .map(item => {
            if (item.formType == 'related_catalog') {
              item.fieldName = 'catalogId'
            }
            return item
          })
      )
    },
    searchFieldInfo () {
      const qrcodeEnabled = this.initData?.productConfig?.qrcodeEnabled || false;
      return (
        formatFields(this.onlyProductFields, qrcodeEnabled)
      )
    },
    productTypes () {
      return this.initData.productConfig.productType || [];
    },
    panelWidth () {
      return `${420 * this.columnNum}px`;
    },
    selectedIds () {
      return this.multipleSelection.map((p) => p.id);
    },
    exportColumns () {
      let arr = [
        {
          label: this.$t('product.type.productId'),
          field: 'productId',
          export: true,
          exportAlias: 'productId',
          tableName: 'product'
        },
        {
          label: this.$t('common.form.type.customerName'),
          field: 'customerName',
          export: true,
          exportAlias: 'customerName',
          tableName: 'product'
        },
        {
          label: this.$t('common.form.type.customerNo'),
          field: 'customerSN',
          export: true,
          exportAlias: 'customerSN',
          tableName: 'product'
        },
        {
          label: this.$t('common.label.customerTag'),
          field: 'customerLabel',
          export: true,
          exportAlias: 'customerLabel',
          tableName: 'product'
        },
        ...this.columns
      ].map((field) => {
        if (
          ['customer', 'productTemplate', 'remindCount'].some(
            (key) => key === field.fieldName
          )
          || field.formType === 'info'
        ) {
          field.export = false;
        } else {
          field.export = true;
        }

        if ('qrcodeId' == field.fieldName) {
          field.export = Boolean(this.initData.productConfig.qrcodeEnabled);
        }

        if ('qrcodeId' == field.fieldName) {
          field.export = Boolean(this.initData.productConfig.qrcodeEnabled);
        }
        // 标准版下产品类型导出字段不对，暂时简单处理下，后续理清楚~
        if (field.fieldName === 'catalogId') {
          field = {...field}
          field.fieldName = 'pathName'
          field.field = 'pathName'
        }

        return field;
      });

      // 导出子表单（服务商）
      let serviceSubField = []
      this.columns.forEach(item => {
        if(item?.setting?.isSubForm) {
          let columns = item.subFormFieldList || []
          columns.forEach(sub => {
            sub.value = sub.fieldName
            sub.label = sub.displayName
            sub.field = sub.fieldName
            sub.export = true
          })
          serviceSubField.push({
            value: item.fieldName,
            label: item.displayName,
            columns
          })
        }
      })

      let arr_ = [
        {
          label: this.$t('product.productMessage'),
          value: 'productExport',
          columns: arr.filter(item => item.tableName == 'product' && item.fieldName != 'serviceProviders' && item.formType !== FieldTypeMappingEnum.JsCodeBlock),
        },
        // {
        //   label: "产品类型信息",
        //   value: "catalogExport",
        //   columns: arr.filter(item => item.tableName == "catalog"),
        // },
        ...serviceSubField,
        ...this.enabledCardList
      ];
      const hasCatalogFiled = arr.some(item => item.tableName == "catalog")
      // 如果返回的有产品类型字段就显示产品类型信息
      if(hasCatalogFiled) {
        arr_.splice(1, 0, {
          label: this.$t('product.productType.text.text3'),
          value: "catalogExport",
          columns: arr.filter(item => item.tableName == "catalog"),
        })
      }
      return arr_
    },
    smsRest () {
      return this.initData.smsRest || 0;
    },
    // 是否显示批量操作
    isShowBatchOperation() {
      // TODO: 暂时不显示了 等容器化按钮组做了再展示
      return false
      return (
        this.isShowCreateSmartPlan || (this.triggerGray && this.triggerList.length) || (this.editedPermission === 3 && this.bindCustomer && this.isShowSendSMS)
        || this.isShowEmail || (this.createdActivityPermission && this.isShowProductSendActivitySurvey) || (this.searchModel.hasBindCustomer == 0 && this.showBindCustomer)
        || this.editedPermission === 3 || this.deletePermission
      )
    },
    isShowCustomerRemind () {
      return this._isShowProductRemind;
    },
    isShowEmail() {
      const RootWindow = getRootWindow(window)
      return (RootWindow.grayAuth?.emailCommon || false) || this._isShowProductSendEmail;
    },
    isShowSendSMS() {
      return this._isShowProductSendSMS;
    },
    isShowProductSendActivitySurvey() {
      return this._isShowProductSendActivitySurvey;
    },
    // 华大基因灰度
    isBgiPrivate() {
      const RootWindow = getRootWindow(window)
      return Boolean(RootWindow.grayAuth?.bgiPrivate)
    },
    createdActivityPermission() {
      return this.auth.ACTIVITIES_CREATE && this.auth.ACTIVITIES_EDIT;
    },
  },
  filters: {
    formatTags ({ customer }) {
      if (!customer) return '';
      if (!customer.tags || !customer.tags.length) return '';
      return customer.tags.map((t) => t.tagName).join(' ');
    },
    formatDate (val) {
      if (!val) return '';
      return formatDate(val, 'YYYY-MM-DD HH:mm:ss');
    },
    formatDate2 (val) {
      if (!val) return '';
      return formatDate(val, 'YYYY-MM-DD');
    },
    displaySelect (value) {
      if (!value) return null;
      if (value && typeof value === 'string') {
        return value;
      }
      if (Array.isArray(value) && value.length) {
        return value.join('，');
      }
      return null;
    },
    // 表格服务商字段解析
    serviceProviderColumnValue(value) {
      if (!value || !Array.isArray(value) || !value.length) return '';

      return value
        .map(item => item.providerName || item.tagName)
        .join('，');
    }
  },
  watch:{
    currentView:{
      async handler(){
        await this.buildColumns();
      },
      immediate:true
    },
  },
  created(){
    // 插入预置视图
    if(this.productCreateUnBindCustomer){
      let list = [
        // { name:'全部产品', id:-1 },
        { name:this.$t('product.list.associatedCustomer'), id:1 },
        { name:this.$t('product.list.unassociatedCustomer'), id:0 }
      ]
      list.forEach(item=>{
        this.preViews.push({
          viewId: 'product_'+item.id,
          viewName: item.name,
          searchModel: [{
            fieldName: 'productCommonSearch',
            operator: '',
            value:{
              hasBindCustomer:item.id
            }
          }],
          authEdit: false,
          visibleType: 1,
          isPre:true
        })
      })
    }
    if(this.pageButtonSetGray){
      this.getPageButtonListForView(ButtonGetTriggerModuleEnum.Product, ButtonSetDetailForShowPositionEnum.PcList, {}, (list)=>{
        this.pageButtonList = list
      })
    }
  },
  async mounted () {
    try {
      await this.recoverCommonUse();
    } catch (error) {
      console.error('recoverCommonUse', error)
    }

    try {
      // 页面参数中有viewNo时说明是复制的视图地址
      const query = parse(window.location.search) || {}
      const viewNo = query.viewNo || ''
      let viewData = {}
      if (viewNo) {
        const list = await fetchViewportList('product')
        viewData = (list || []).find(item => viewNo === item.viewNo)
      }
      // 页面参数中有viewNo时不执行search方法，因为viewportSearchModel更新后会执行一遍search
      const needSearch = (viewNo && viewData && viewData.searchModel) ? false : true
      await this.resetPage(needSearch)
      if (!needSearch) {
        this.chooseView(viewData)
      }
      // 高级搜索设置默认值
      this.setCustomerDefaultValue()

      this.getEnabledCardInfo();
      this.getTriggerList(['product', 'PRODUCT_ADDITIONAL'])
      this.buttonStorageData = await this.getButtonLocalStorageData(this.buttonStorageModule, this.buttonStorageKey)
    } catch(error) {
      console.error('setCustomerDefaultValue', error)
    }

    // [tab_spec]标准化刷新方式
    window.__exports__refresh = this.resetPage;

    this.$eventBus.$on(
      'product_list.update_product_list_remind_count',
      this.updateProductRemindCount
    );
    let that_ = this;
    // 监听切换后需要重新计算列表高度 后续可以用activated生命周期替换
    window.addEventListener('message', (event)=> {
      const {action, data} = event.data;
      if (action == 'shb.frame.activatedPage'){
        that_.$nextTick(()=> {
          that_.knowTableContainerHeight();
        })
      }
    });
    this.$nextTick(()=> {
      this.knowTableContainerHeight()
      window.onresize = _.debounce(()=>{
        that_.knowTableContainerHeight()
      }, 500)
    })

  },
  beforeDestroy () {
    this.$eventBus.$off(
      'product_list.update_product_list_remind_count',
      this.updateProductRemindCount
    );
  },
  methods: {
    getPageButtonListForView,
    // 自定义按钮点击事件
    handlePageButtonClick(item) {
      pageButtonClick(item, this.multipleSelection, {
        fields: this.fields,
        multipleSelection: this.multipleSelection,
        js_vm: this,
      }, ()=>{
        this.pageButtonLoading = true
      }, null, ()=>{
        this.pageButtonLoading = false
      })
    },
    /** 打开富文本弹窗 */
    openRichtextVisible(row, column) {
      const richtextId = row?.attribute?.[column.fieldName] || ''
      this.$refs?.baseViewRichTextRef?.openDialog(richtextId)
    },
    setTableData(){
      if(!this.page?.list?.length || !this.columns?.length) return this.tableData = []
      this.tableData = disposeFormListViewTime(this.page.list, this.columns)
    },
    // 高级搜索设置客户默认值
    setCustomerDefaultValue () {
      const query = parse(window.location.search) || {};

      if(!query.customerId) return;
      this.viewportSearchModel = [{
        fieldName: 'customer',
        value: [
          {
            name: query.customerName,
            id: query.customerId
          }
        ],
        operator: 'eq'
      }]
    },
    formattedOpenDataTooltip(record = '') {
      return formattedOpenDataTooltip(record || '')
    },
    refresh(){
      this.multipleSelection = []
      this.$refs.multipleTable.clearSelection();
      setTimeout(() => {
        this.search()
      }, 1000);
    },
    // 预览/关联二维码
    bindCode(product){
      this.productId = product.id;
      if(!product.qrcodeId){
        this.$refs.publicDialog.open();
      }else{
        this.qrcodeData = {
          productId:this.productId,
          qrcodeId:product.qrcodeId,
          productName:product.name,
          productSN:product.serialNumber
        }
        this.$refs.qrcodeDialog.open();
      }
    },
    // 绑定成功
    dialogBind(e){
      bindQrcode({
        productId: this.productId,
        qrocdeId: e.qrcodeId,
      })
        .then((res) => {
          if (res.status)
            return this.$platform.notification({
              title: this.$t('common.base.fail'),
              message: res.message || this.$t('product.tips.unknownError'),
              type: 'error',
            });

          this.$refs.publicDialog.close();
          // ES同步有延迟，前端做了延迟刷新
          setTimeout(()=>{
            this.search();
          }, 1000)
          return this.$platform.notification({
            title: this.$t('product.tips.bindQrcodeSuccess'),
            type: 'success',
          });
        })
        .catch((e) => console.error('e', e))
        .finally(() => {
          this.$refs.publicDialog.changeLoading(false);
        });
    },
    async resetPage (needSearch = true) {
      // 获取产品动态字段
      try {
        // catalogFlag 为true就返产品模版相关的字段，不传或者false就没有
        let res = await getProductFields({ isFromSetting: false, catalogFlag: true });

        this.dynamicFields = smoothLogisticsField(res.data || [])

        // 如果有物流字段，需要查询检查是否还有物流剩余次数
        if(this.dynamicFields?.some(item => item.formType === 'logistics')){
          this.checkQuota();
        }

        // 自定义字段是否重复报修 修改下拉框的值
        this.dynamicFields.forEach(f => {
          if (f.fieldName == 'isRepeatRepair') {
            f.setting.dataSource = [{
              text: this.$t('common.base.all'),
              value: ''
            }, {
              text: this.$t('common.base.yes'),
              value: '是'
            }, {
              text: this.$t('common.base.no'),
              value: '否'
            }]
          }
        })
        await this.buildColumns();
        this.getSelectCount();
      } catch (error) {
        await this.buildColumns();
        console.error('product-list fetch product fields error', error);
      }
      await this.revertStorage();
      if (needSearch) {
        this.search();
      }

      if (!this.viewedPermission) {
        this.filterTeams = this.matchTags(this.teamsWithChildTag.slice());
      }
    },
    getAddress (field) {
      return formatAddress(field);
    },
    getRelatedTask (field) {
      return Array.isArray(field)
        ? field.map((item) => item.taskNo).join(',')
        : '';
    },
    // 处理人员显示
    getUserName (field, value) {
      // 多选
      if (Array.isArray(value)) {
        return value.map((i) => i.displayName || i.name).join(',');
      }

      let user = value || {};
      return user.displayName || user.name;
    },
    getUserIds (value) {
      // 多选
      if (Array.isArray(value)) {
        return value.map((i) => i.staffId);
      }

      let user = value || {};
      return [user.staffId];
    },
    openOutsideLink (e) {
      let url = e.target.getAttribute('url');
      if (!url) return;
      if (!/http/gi.test(url))
        return this.$platform.alert(this.$t('product.list.tips.httpRequireTips'));
      this.$platform.openLink(url);
    },
    buildTextarea (value) {
      return value
        ? value.replace(link_reg, (match) => {
          return `<a href="javascript:;" target="_blank" url="${match}">${match}</a>`;
        })
        : '';
    },
    powerfulSearch () {
      this.searchModel.pageNum = 1;

      this.search();
    },
    formatCustomizeAddress (ad) {
      return formatAddress(ad);
    },

    openProductTab (productId) {

      if (!this.globalIsHaveProductViewDetailAuth) return

      let fromId = window.frameElement.getAttribute('id');
      // this.$platform.openTab({
      //   id: `product_view_${productId}`,
      //   title: '产品详情',
      //   close: true,
      //   url: `/customer/product/view/${productId}?noHistory=1`,
      //   fromId,
      // });
      openAccurateTab({
        type: PageRoutesTypeEnum.PageProductView,
        key: productId,
        params: 'noHistory=1',
        fromId
      })
    },
    // 客户标签
    searchCustomerTags(custoemrTags) {
      if (_.isEqual(this.customerSelectedTagIdList, custoemrTags)) return

      this.customerSelectedTagIdList = custoemrTags
      this.search()
    },
    // 搜索
    search () {
      this.$nextTick(()=>{
        // 滚动至表格顶部
        this.$refs.multipleTable?.$refs?.bodyWrapper?.scrollTo(0, 0)
      })
      const params = this.buildParams();
      params.catalogFlag = true;
      this.loading = true;

      return getProductV2(params)
        .then((res) => {
          // this.page = Page.as(Object.freeze(res.result));
          if(!res.success) {
            this.$platform.alert(res?.message || this.$t('common.base.requestError'));
            this.page.list = [];
            this.page.pageNum = 1;
            return
          };
          let { number, content, totalPages, totalElements, size } = res.result;
          if (content.length) content = content.map((item) => {
            // catalogEntity里面也有id属性，所以先保存下item.id
            const id = item.id
            const attribute = item.attribute
            if (item.catalogEntity) {
              item = { ...item, ...item.catalogEntity };
              item['catalogId'] = item.catalogId || ''
              item.productDesc = item.catalogEntity.productDesc || ''
              if (item.catalogEntity.attribute) {
                item.attribute = { ...attribute, ...item.catalogEntity.attribute }
              } else {
                item.attribute = attribute
              }
              // 将之前的item.id再赋值回去
              item.id = id
            } else {
              // 如果catalogEntity为空取catalog
              item = { ...item, ...item.catalog };
              item['catalogId'] = item.catalogId || ''
              if (item.catalog.catalogAttribute) {
                item.attribute = { ...item.attribute, ...item.catalog.catalogAttribute }
              }
            }

            // 如果开启了产品目录分列展示
            if (item.pathName && this.productMenuSplit) {
              const pathName = item.pathName.split('/')
              // 如果只有一级产品类型，产品目录显示空
              if (pathName.length > 1) {
                item.pathName = pathName[pathName.length - 1]
                const productMenu = pathName.slice(0, pathName.length - 1)
                item.productMenu = productMenu.join(' / ')
              } else {
                item.productMenu = ''
              }
            }

            // 产品状态
            if(item.productStatus === null) item.productStatus = true

            return item
          })

          this.page['list'] = disposeFormListViewTime(content, this.columns);
          this.page['total'] = totalPages;
          this.page['totalElements'] = totalElements
          this.page['pageNum'] = number;
          this.page['pageSize'] = size
          this.matchSelected();
        })
        .then(() => this.loading = false)
        .catch((e) => console.error('fetch product catch an error', e));
    },
    buildParams () {
      const systemTypes = ['customerManager', 'createUser', 'synergies','tags','addressDetail']
      const sm = Object.assign({}, this.searchModel);
      let params = {
        searchCondition: sm.searchCondition,
        keyword: getSystemNormalSearchInputForLength(sm.keyword),
        pageSize: sm.pageSize,
        pageNum: sm.pageNum,
        tenantTagIdList: this.customerSelectedTagIdList,
        catalogState: sm.catalogState,
        hasBindCustomer:sm.hasBindCustomer,
        systemConditions:sm.systemConditions||[],
        conditions:sm.conditions||[]
      };

      if (Object.keys(sm.orderDetail || {}).length) {
        params.orderDetail = sm.orderDetail;
      }

      // if (
      //   Object.keys(sm.moreConditions).length > 1
      //   || sm.moreConditions.conditions.length
      // ) {
      //   params = {
      //     ...params,
      //     ...sm.moreConditions,
      //   };
      // }

      params.systemConditions.forEach(item=>{
        if(systemTypes.indexOf(item.property) > -1){
          item.jsonDataField = item.property
          if(item.property=='tags'){
            item.property = 'id'
          }else if(item.property=='addressDetail'){
            item.property = 'adAddress'
            item.jsonDataField = 'mainAddress'
          }else{
            item.property = 'userId'
          }
        }
      })
      const allParams = Object.assign(params)

      params = filterProductSearchParamsInvalidProperty(allParams)

      return params;
    },
    jump (pageNum) {
      this.searchModel.pageNum = pageNum;
      this.search();
    },
    resetParams () {
      window.TDAPP.onEvent('pc：产品管理-重置事件');
      this.searchIncludeMoreConditions = false;
      this.searchModel = {
        searchCondition:'',
        hasBindCustomer:-1,
        keyword: '',
        pageNum: 1,
        pageSize: this.page.pageSize,
        orderDetail: {},
        catalogState: '',
        conditions:[],
        systemConditions:[],
      };

      this.chooseView();
    },
    toImportProduct(cardId) {
      this.productAddOnsImportTemplateUrl = `${productAddOnsImportTemplate}?cardId=${cardId}`
      this.productAddOnsImportUrl = `${productAddOnsImport}?cardId=${cardId}`
      this.$refs.importAddOnModal?.open();
    },
    openDialog (action) {
      if(action === 'bindCustomer'){
        if (!this.selectedIds.length) {
          return this.$platform.alert(this.$t('product.list.tips.bindCustomer1'));
        }
        window.TDAPP.onEvent('pc：产品管理-关联客户');
        this.$refs.customerBind.open();
      }

      if (action === 'sendMessage') {
        window.TDAPP.onEvent('pc：产品管理-发送短信事件');
        this.$refs.messageDialog.openSendMessageDialog();
      }

      if (action === 'sendEmail') {
        this.$refs.emailDialog.openDialog();
      }

      if (action === 'edit') {
        window.TDAPP.onEvent('批量编辑	pc：产品管理-批量编辑事件');
        this.$refs.batchEditingDialog.open();
      }

      if (action === 'remind') {
        window.TDAPP.onEvent('批量提醒	pc：产品管理-批量提醒事件');
        this.$refs.batchRemindingDialog.openBatchRemindingDialog();
      }

      if (action === 'importProduct') {
        this.$refs.importProductModal.open();
      }

      if (action === 'update') {
        // if (!this.multipleSelection || !this.multipleSelection.length) {
        //   return this.$platform.alert('您尚未选择数据，请选择数据后点击批量更新');
        // }
        this.$refs.batchUpdateDialog.openBatchUpdateCustomerDialog();
      }
    },
    // operation
    async deleteProducts () {
      window.TDAPP.onEvent('pc：产品管理-删除事件');
      if (!this.multipleSelection.length) {
        return this.$platform.alert(this.$t('product.list.tips.deleteProducts1'));
      }

      try {
        if (!(await this.$platform.confirm(this.$t('product.list.tips.deleteProducts2')))) return;

        const ids = this.multipleSelection.map((p) => p.id).join(',');
        this.loading = true;
        const res = await deleteProductByIds(ids);
        this.loading = false;

        if (!res || res.status)
          return this.$platform.notification({
            title: this.$t('common.base.fail'),
            type: 'error',
            message: res.message || this.$t('product.tips.unknownError'),
          });
        this.$platform.notification({
          title: this.$t('common.base.deleteSuccess'),
          type: 'success',
        });
        this.multipleSelection = [];
        // 删除之后留1S延迟给es同步
        setTimeout(()=>{
          this.search();
        }, 1000)
      } catch (e) {
        this.loading = false;
        console.error('e', e);
      }
    },
    // 批量添加提醒成功后，更新产品的提醒数量
    updateProductRemindCount () {
      let count = 0;
      this.page.list = this.page.list.map((product) => {
        count = product.attribute.remindCount || 0;

        if (this.selectedIds.some((id) => id === product.id)) {
          product.attribute.remindCount = count + 1;
        }

        return product;
      });

      this.matchSelected();
    },
    // table method
    handleSelection (selection) {
      let tv = this.selectionCompute(selection);

      let original = this.multipleSelection.filter((ms) =>
        this.page.list.some((cs) => cs.id === ms.id)
      );

      let unSelected = this.page.list.filter((c) =>
        original.every((oc) => oc.id !== c.id)
      );

      if (tv.length > this.selectedLimit) {
        this.$nextTick(() => {
          original.length > 0
            ? unSelected.forEach((row) => {
              this.$refs.multipleTable.toggleRowSelection(row, false);
            })
            : this.$refs.multipleTable.clearSelection();
        });
        return this.$platform.alert(this.$t('common.base.tip.choiceLimit', {limit: this.selectedLimit}));
      }

      this.multipleSelection = tv;

      this.$refs.baseSelectionBar?.openTooltip();
      this.$nextTick(()=>{
        this.knowTableContainerHeight()
      })
    },
    // 计算已选择
    selectionCompute (selection) {
      let tv = [];

      tv = this.multipleSelection.filter((ms) =>
        this.page.list.every((c) => c.id !== ms.id)
      );
      tv = _.uniqWith([...tv, ...selection], _.isEqual);

      return tv;
    },
    sortChange (option) {
      try {
        const { prop, order } = option;
        if (!order) {
          this.searchModel.orderDetail = {};
          return this.search();
        }
        const sortedField = this.productFields.filter((sf) => sf.fieldName === prop)[0] || {};

        let isSystem = sortedField.isSystem || 0;

        let sortModel = {
          isSystem,
          sequence: order === 'ascending' ? 'ASC' : 'DESC',
          column: isSystem ? `${prop}` : prop,
        };

        if (
          prop === 'createTime'
          || prop === 'updateTime'
          || sortedField.formType === 'date'
          || sortedField.formType === 'datetime'
        ) {
          sortModel.type = 'date';
        } else {
          sortModel.type = sortedField.formType;
        }

        if (isQualityInfoStartTimeField(sortedField)) {
          sortModel.column = 'qualityStartTime'
        }
        if(isQualityInfoEndTimeField(sortedField)) {
          sortModel.column = 'qualityEndTime'
        }

        this.searchModel.orderDetail = sortModel;

        this.search();
      } catch (e) {
        console.error('e', e);
      }
    },
    handleSizeChange (pageSize) {
      this.saveDataToStorage('pageSize', pageSize);
      this.searchModel.pageSize = pageSize;
      this.searchModel.pageNum = 1;
      this.search();
    },
    toggleSelection (rows) {
      let isNotOnCurrentPage = false;
      let item = undefined;
      let row = undefined;

      if (rows) {
        for (let i = 0; i < rows.length; i++) {
          row = rows[i];
          isNotOnCurrentPage = this.page.list.every((item) => {
            return item.id !== row.id;
          });
          if (isNotOnCurrentPage) return;
        }
        rows.forEach((row) => {
          this.$refs.multipleTable.toggleRowSelection(row);
        });
      } else {
        this.$refs.multipleTable.clearSelection();
        this.multipleSelection = [];
      }
    },

    removeFromSelection (c) {
      if (!c || !c.id) return;

      this.multipleSelection = this.multipleSelection.filter(
        (ms) => ms.id !== c.id
      );
      this.multipleSelection.length < 1
        ? this.toggleSelection()
        : this.toggleSelection([c]);
    },

    // 选择列 s

    /**
     * @description 表头更改
     */
    headerDragend (newWidth, oldWidth, column, event) {
      let data = this.columns
        .map((item) => {
          if (item.fieldName === column.property) {
            item.width = column.width;
          }
          return item;
        })
        .map((item) => {
          return {
            field: item.field,
            show: item.show,
            width: item.width,
          };
        });
      this.modifyColumnStatus({ type: 'column', data });
    },

    /**
     * @description 修改选择列设置
     * @param {Object} event 事件对象
     */
    modifyColumnStatus (event) {
      let columns = event.data || [],
        colMap = columns.reduce(
          (acc, col) => (acc[col.field] = col) && acc,
          {}
        );
      this.columns.forEach((col) => {
        let newCol = colMap[col.field];
        if (null != newCol) {
          this.$set(col, 'show', newCol.show);
          this.$set(col, 'width', newCol.width);
        }
      });

      this.saveColumnStatusToStorage();
    },
    showAdvancedSetting () {
      window.TDAPP.onEvent('pc：产品管理-选择列事件');
      this.$refs.advanced.open(this.columns);
    },
    /**
     * @description 修改选择列设置
     * @param {Object} event 事件对象
     */
    saveColumnStatus (event) {
      let columns = event.data || [];

      this.columns = [];

      this.$nextTick(() => {
        this.$set(this, 'columns', columns.slice());
        this.tableKey = (Math.random() * 1000) >> 2;
        this.saveColumnStatusToStorage();
      });
      this.$message.success(this.$t('common.base.saveSuccess'));
    },

    async saveColumnStatusToStorage () {
      const localStorageData = await this.getLocalStorageData();
      let columnsStatus = null;
      // 判断是否存储选择列
      const columnsList = this.columns.map((c) => ({
        field: c.field,
        show: c.show,
        width: c.width,
        fixLeft: c.fixLeft
      }));

      if(localStorageData[this.currentView?.viewId]){
        try{
          localStorageData[this.currentView?.viewId][
            `${this.selectColumnState}`
          ] = columnsList;
          columnsStatus = localStorageData[this.currentView?.viewId];
        }catch(err){
          console.error(err)
        }
      }else if (localStorageData.columnStatus) {
        localStorageData.columnStatus[
          `${this.selectColumnState}`
        ] = columnsList;
        columnsStatus = localStorageData.columnStatus;
      } else {
        columnsStatus = {
          [`${this.selectColumnState}`]: columnsList,
        };
      }

      if(this.currentView?.viewId){
        this.saveDataToStorage(this.currentView?.viewId,columnsStatus)
      }else{
        this.saveDataToStorage('columnStatus', columnsStatus); //默认选择列保存
      }
    },

    // 选择列 e

    async buildColumns() {
      const localStorageData = await this.getLocalStorageData();
      console.log('================================', localStorageData)

      // let columnStatus = localStorageData.columnStatus && localStorageData.columnStatus[this.selectColumnState]
      let columnStatus = []
      if(this.currentView?.viewId&&localStorageData[this.currentView?.viewId]){
        columnStatus =localStorageData[this.currentView?.viewId][this.selectColumnState]
      }else{
        columnStatus = localStorageData.columnStatus && localStorageData.columnStatus[this.selectColumnState]
      }
      columnStatus = columnStatus || [];
      // let localColumns = columnStatus
      //   .map((i) => (typeof i == 'string' ? { field: i, show: true } : i))
      //   .reduce((acc, col) => (acc[col.field] = col) && acc, {});

      let localColumns = columnStatus
        .map((i) => (typeof i == 'string' ? { field: i, show: true } : i))
        .reduce((acc, col, currentIndex) => {
          acc[col.field] = {
            field: col,
            index: currentIndex,
          };
          return acc;
        }, {});

      let fields = [
        ...this.productFields,
        ...customerSystemFields
      ];
      if (Array.isArray(columnStatus) && columnStatus.length > 0) {
        fields = this.buildSortFields(fields, localColumns);
      }
      fields = smoothQualityInfoFieldForTable(fields)

      this.columns = fields
        .filter(
          (f) =>
            f.formType !== 'attachment'
            && f.formType !== 'separator'
            && f.formType !== 'info'
            && f.formType !== 'autograph'
            && f.formType !== FieldTypeMappingEnum.JsCodeBlock
        )
        .map((field) => {
          let sortable = false;
          let minWidth = null;

          if (
            ['date', 'datetime', 'number'].indexOf(field.formType) >= 0
          ) {
            sortable = 'custom';
            minWidth = 100;
          }

          if (['type', 'serialNumber', 'qrcodeId'].includes(field.fieldName)) {
            sortable = 'custom';
          }

          if (field.displayName.length > 4) {
            minWidth = field.displayName.length * 20;
          }

          if (sortable && field.displayName.length >= 4) {
            minWidth = getSortableMinWidth(field)
          }

          if (
            field.formType === 'datetime'
            || field.fieldName === 'updateTime'
            || field.fieldName === 'createTime'
          ) {
            minWidth = Math.max(150, minWidth);
          }

          return {
            ...field,
            label: field.displayName,
            field: field.fieldName,
            formType: field.formType,
            minWidth: typeof minWidth == 'number' ? minWidth : `${minWidth}px`,
            sortable,
            isSystem: field.isSystem,
          };
        })
        .map((col) => {
          let show = col.show === true;
          let { width } = col;
          let localField = (localColumns[col.field] && localColumns[col.field].field) || null;

          let fixLeft = localField?.fixLeft || null;

          if (null != localField) {
            width = typeof localField.width == 'number'
              ? `${localField.width}px`
              : `${localField.width}`.indexOf('px') ? localField.width : '';
            show = localField.show !== false;
          }

          col.show = show;
          col.width = width;
          col.type = 'column';
          col['fixLeft'] = fixLeft && 'left'
          return col;
        });
    },

    buildSortFields(originFields = [], fieldsMap = {}) {
      let fields = [];
      let unsortedFields = [];

      originFields.forEach((originField) => {
        let { fieldName } = originField;
        let field = fieldsMap[fieldName];

        if (field) {
          let { index } = field;
          fields[index] = originField;
        } else {
          unsortedFields.push(originField);
        }
      });

      // 存储列数据之后，如果存在列被删除的情况，可能产生空值，需要过滤，否则其他地方没做判断会报错
      return fields.filter(v => v).concat(unsortedFields);
    },

    /**
     * 导出服务商子表单数据
     */
    buildSubExportData(fieldName, list = []) {
      if(list.length < 1) return {}
      return {
        [fieldName]: list
      }
    },
    /**
     * @description 构建导出参数
     * @return {Object} 导出参数
     */
    buildExportParams (checkedMap, ids, exportOneRow) {
      const {
        productExport,
        catalogExport,
        serviceProviders
      } = checkedMap
      const Params = Object.assign({}, this.params);
      const rootWindow = getRootWindow(window);
      const {
        loginUser
      } = this.initData;

      let exportAll = !ids || !ids.length;
      const all = exportAll ? {
        ...this.buildParams(),
        productIds: this.selectedIds,
        tagIds: loginUser.tagIds,
        tenantId: JSON.parse(rootWindow._init).user.tenantId,
      } : {
        productIds: this.selectedIds,
        tagIds: loginUser.tagIds,
        tenantId: JSON.parse(rootWindow._init).user.tenantId,
      };

      let exportSearchModel = {

      };
      let params = {
        exportSearchModel: JSON.stringify({
          ...all,
          ...{
            exportTotal: exportAll
              ? this.page.totalElements : this.selectedIds.length,
          },
        }),
      };

      // 附加
      let cardFieldChecked = []
      let cardChecked = [];
      for (let key in checkedMap) {
        if (key.indexOf('annexChecked') !== -1) {
          cardFieldChecked = [...cardFieldChecked, ...checkedMap[key]];
          if(checkedMap[key].length > 0) cardChecked.push(key.split('#')[1]);
        }
      }

      /** ********************* *********************/
      // 产品信息
      let export_product = this.exportData(0, productExport)
      // 附加信息
      let export_card_field = cardFieldChecked.length ? this.exportData(3, cardFieldChecked, 'cardFieldChecked') : cardFieldChecked

       // 子表单（服务商）
      let export_subFields = JSON.stringify(this.buildSubExportData('serviceProviders', serviceProviders))
      // 产品类型信息
      let export_catalog = this.exportData(1, catalogExport)

      params['exportOneRow'] = exportOneRow
      params['data'] = exportAll ? '' : this.selectedIds.join(',');
      if(export_catalog && export_catalog.length) params["catalogExport"] = export_catalog.join(",");
      params['productExport'] = export_product.join(',');
      params['subFieldNameMap'] = export_subFields;
      params['cardChecked'] = cardChecked.join(',');
      params['cardFieldChecked'] = export_card_field.filter(item => {
        return item;
      }).join(',');

      return params;
    },
    /**
     * 导出数据
     */
    exportData (number, list = [], type) {
      const export_list = this.exportColumns;
      if (!list.length) return [];
      if (number === 3) {
        let cardField = []
        export_list.filter((item, index) => {
          return type === 'cardFieldChecked' ? item.value !== 'productExport' : index > 2;
        }).forEach(v => {
          v.columns.forEach(item => {
            cardField.push(item)
          })
        })
        return cardField.map(v => {
          let bool = list.some(item => {
            if (v.exportAlias) {
              return v.exportAlias === item
            }
            return v.fieldName === item

          })
          if (bool) {
            return v.exportAlias ? v.exportAlias : v.fieldName
          }
        }).filter(item => {
          return item
        })
      }

      return export_list[number].columns.map(v => {
        let bool = list.some(item => {
          if (v.exportAlias) {
            return v.exportAlias === item
          }
          return v.fieldName === item

        })
        if (bool) {
          return v.exportAlias ? v.exportAlias : v.fieldName
        }
      }).filter(item => {
        return item
      })
    },
    /** 检测导出条数 */
    checkExportCount (ids, max) {
      let exportAll = !ids || !ids.length;
      /**
       * @des 解除导出前端限制5000条限制由后端限制
       * @see http://zentao.shb.ltd/index.php?m=task&f=view&taskID=6610
       */
      return null;
    },

    exportProduct (exportAll) {
      let ids = [];
      let fileName = `${formatDate(safeNewDate(), 'YYYY-MM-DD')}产品数据.xlsx`;
      if (!exportAll) {
        if (!this.multipleSelection.length)
          return this.$platform.alert(this.$t('common.base.tip.exportUnChooseTip'));
        ids = this.selectedIds;
      }
      this.$refs.exportPanel.open(ids, fileName);
    },
    showLatestUpdateRecord (row) {
      if (row.latesetUpdateRecord) return;
      getUpdateRecord({
        productId: row.id,
      })
        .then((res) => {
          if (!res || res.status) return;

          this.page.list = this.page.list.map((c) => {
            if (c.id === row.id) {
              c.latesetUpdateRecord = res.data;
            }
            return c;
          });

          this.matchSelected();
        })
        .catch((e) => console.error('e', e));
    },

    createCustomerTab (productId) {
      let fromId = window.frameElement.getAttribute('id');

      // this.$platform.openTab({
      //   id: `customer_view_${productId}`,
      //   title: '客户信息',
      //   close: true,
      //   url: `/customer/view/${productId}?noHistory=1`,
      //   fromId,
      // });
      openAccurateTab({
        type: PageRoutesTypeEnum.PageCustomerView,
        key: productId,
        params: 'noHistory=1',
        fromId
      })
    },

    createTemplateTab (templateId) {
      let fromId = window.frameElement.getAttribute('id');

      // this.$platform.openTab({
      //   id: `product_template_view_${templateId}`,
      //   title: '产品模板',
      //   close: true,
      //   url: `/product/detail/${templateId}?noHistory=1`,
      //   fromId,
      // });
      openAccurateTab({
        type: PageRoutesTypeEnum.PageProductTemplate,
        key: templateId,
        params: 'noHistory=1',
        fromId
      })
    },
    goToCreate () {
      window.TDAPP.onEvent('pc：产品管理-新建事件');
      // window.location = '/customer/product/create';
      let fromId = window.frameElement.getAttribute('id');

      // this.$platform.openTab({
      //   id: 'customer_product_create',
      //   title: '新建产品',
      //   url: '/customer/product/create',
      //   reload: true,
      //   close: true,
      //   fromId,
      // });
      openAccurateTab({
        type: PageRoutesTypeEnum.PageCreateProduct,
        reload: true,
        fromId
      })
    },
    async getLocalStorageData() {
      try {
        let dataStr = storageGet(PRODUCT_LIST_LOCALSTORAGE_20_11_25) || '{}';
        if(dataStr === '{}'){
          dataStr = await getServerCach(PRODUCT_LIST_LOCALSTORAGE_20_11_25, {}, 'product', PRODUCT_LIST_LOCALSTORAGE_20_11_25) || {}
          dataStr = JSON.stringify(dataStr)
          storageSet(PRODUCT_LIST_LOCALSTORAGE_20_11_25, dataStr);
        }
        return JSON.parse(dataStr);
      }catch(err){
        return {};
      }
    },
    async saveDataToStorage (key, value) {
      const data = await this.getLocalStorageData();
      data[key] = value;
      setServerCach(PRODUCT_LIST_LOCALSTORAGE_20_11_25, data, 'product', PRODUCT_LIST_LOCALSTORAGE_20_11_25)
      storageSet(PRODUCT_LIST_LOCALSTORAGE_20_11_25, JSON.stringify(data));
    },
    async getBindList(){
      this.searchModel.pageNum = 1;
      this.hasBindCustomerText = this.searchModel.hasBindCustomer===-1?this.$t('product.list.allProduct'):(this.searchModel.hasBindCustomer===1?this.$t('product.list.associatedCustomer'):this.$t('product.list.unassociatedCustomer'))
      await this.buildColumns()
      this.search()
    },
    async revertStorage () {
      const { pageSize, column_number } = await this.getLocalStorageData();
      if (pageSize) {
        this.searchModel.pageSize = pageSize;
      }
      if (column_number) this.columnNum = Number(column_number);
    },
    // 匹配选中的列
    matchSelected () {
      if (!this.multipleSelection.length) return;

      const selected = this.page.list.filter((c) => {
        if (this.multipleSelection.some((sc) => sc.id === c.id)) {
          this.multipleSelection = this.multipleSelection.filter(
            (sc) => sc.id !== c.id
          );
          this.multipleSelection.push(c);
          return c;
        }
      }) || [];

      this.$nextTick(() => {
        this.toggleSelection(selected);
      });
    },
    // 获取团队列表
    getTeamList (params) {
      return this.getBizTeamList(
        params,
        this.filterTeams,
        this.viewedPermission
      );
    },
    // TalkingData事件埋点
    trackEventHandler (type) {
      if (type === 'search') {
        window.TDAPP.onEvent('pc：产品管理-搜索事件');
        return;
      }
      if (type === 'moreAction') {
        window.TDAPP.onEvent('pc：产品管理-更多操作事件');
        return;
      }
    },
    getRowKey (row) {
      return row.id || '';
    },
    /**
     * 创建视角
     */
    createPerspective (item, bool = false) {
      this.searchModel.catalogState = item.value;
      this.selectId = item.value;
      this.searchModel.pageNum = 1;
      this.search();
    },
    /**
     * @description 导出提示
     */
    exportAlert (result, params = {}) {
      this.$platform.alert(result.message);
    },

    getSelectCount () {
      getProductLinkCatalogCount().then(res => {
        this.selectCount = res.result
      })
    },
    toggleStatus(row) {
      const params = {
        productStatus: row.productStatus,
        ids: [row.id]
      }
      updateProductStatus(params).then(res => {
        if(res.success) {
          this.$message.success(this.$t('common.base.tip.operationSuccess'));
        } else {
          this.$message.error(res.message || this.$t('common.base.tip.operationFail'));
        }
      }).catch(err => {
        console.error(err);
      })
    },

    // 移植产品类型表单 s
    previewVideo (e) {
      this.$previewVideo(e);
    },
    previewImg (url, urls = []) {
      if(typeof urls !== 'object'){
        urls = []
      }
      this.$previewElementImg(url, urls);
      // this.$previewImg(url);
    },
    openProductMenuTab (id) {
      openAccurateTab({
        type: PageRoutesTypeEnum.PageProductV2CatalogView,
        key: id,
        params: `id=${id}`,
      })
    },
    // 获取附加组件
    async getEnabledCardInfo(){
      try{
        let { result = [], code, message } = await getEnabledCardInfo({cardType: 'product'});
        if(code === 0){
          this.enabledCardList = result.filter(item => item && item.specialfrom !== '连接器').map((item, index)=>{

            item.fields = [...(item.fields || []), ...[{displayName: this.$t('product.list.operator'),
              fieldName: `cu_${item.id}`}, {displayName: this.$t('product.list.operateTime'),
              fieldName: `ct_${item.id}`}]];

            let columns = item.fields
              .filter(f => f.fieldName !== 'part') // 关联备件字段的【备件】不需要导出 fix bug 17897
              .map((v, i) => {
                return {
                  export: true,
                  label: v.displayName,
                  exportAlias: v.fieldName,
                  ...v,
                };
              });

            return {
              value: `annexChecked#${item.id}`,
              label: `${this.$t('product.additionalComponents')}：${item.name}`,
              inputType: item.inputType,
              columns: columns.filter(f => !['attachment', 'separator', 'autograph', 'info'].includes(f.formType)),
              cardId: item.id,
              cardName: item.name
            };
          })
        }else{
          this.$message.error(message);
        }
      }catch(err){
        console.error(err);
      }
    },

    // 新手引导方法 暂未使用
    guideFunc() {
      this.$nextTick(() => {
        if (storageGet(PRODUCT_PRODUCT_LIST) && storageGet(PRODUCT_PRODUCT_LIST) > 0) this.$Guide().destroy('product-product-list')
        else this.$Guide([{
          content:
            '产品列表，可拖拽改变列表宽',
          haveStep: true,
          nowStep: 1,
          id: 'product-product-list',
          domObj:()=>{
            return document.getElementById('product-product-list-1').getElementsByClassName('el-table__header-wrapper')[0]
          },
          needCover: true,
          finishBtn: 'ok',
        }, {
          content:
            '高级搜索支持自定义条件对目标数据搜索',
          haveStep: true,
          nowStep: 2,
          id: 'product-product-list',
          domId: 'product-product-list-2',
          needCover: true,
          finishBtn: 'ok',
        }, {
          content:
            '选择自定义列展示、数据导出等功能',
          haveStep: true,
          nowStep: 3,
          id: 'product-product-list',
          domId: 'product-product-list-3',
          needCover: true,
          finishBtn: 'ok',
        }], 0, '', (e) => {
          return new Promise((resolve, reject) => {
            resolve()
          })
        }).create().then(res_=>{if(res_)storageSet(PRODUCT_PRODUCT_LIST, '1')})
      })
    },

    /**
     * @des 获取列表当前的可滚动高度
     */
		 knowTableContainerHeight(){
      let min = 440;
      try {
        let window_ = window.innerHeight;
        let header = this.$refs.tableHeaderContainer?.offsetHeight || 0;
        let do_ = this.$refs.tableDoContainer?.offsetHeight || 0;
        let footer = this.$refs.tableFooterContainer?.offsetHeight || 0;
        let selection = this.$refs.BaseSelectionBarComponent?.offsetHeight || 0;
        min = window_ - header * 1 - do_ * 1 - footer * 1 - selection * 1 - 24 - 12 ;
        console.log(window_, header, do_, footer, selection, 'window_, header, do_, footer, selection');
        console.log(min, 'min')
        min = min > 440 ? min : 440;
      } catch (error) {
        console.warn(error, 'error try catch');
      }
      this.$set(this, 'tableContainerHeight', `${min}px`)
    },
    changePackUp(){
      this.packUp = !this.packUp;
      this.$nextTick(()=>{
        this.knowTableContainerHeight()
      })
    },

    // 视图高级搜索改版
    // 高级搜索 ——> 点击搜索按钮
    async handleAdvancedSearch({searchModel = [],searchList = []}){
      this.searchModel = { ...this.searchModel, ...searchModel, pageNum: 1 }
      // minix,混入名为baseSaveShowHandle
      let searchParamsPeer = this.handleShowSave(searchList);

      await this.search()

      if(this.$refs.productSaveRef && typeof this.$refs.productSaveRef.open === 'function') {
        this.$refs.productSaveRef.open(searchParamsPeer, searchList);
      };
    },

    // 处理视图
    genViewport(_v){
      if(!_v || !_v.searchModel) return null
      const viewport = cloneDeep(_v);
      return viewport
    },

    // 选择视图
    chooseView(_v){
      this.currentView = this.genViewport(_v); // 视图设为当前视图
      this.viewportSearchModel = this.currentView?.searchModel || [];
      if(this.currentView?.searchModel[0]?.fieldName === 'productCommonSearch'){
        // 外面固定条件截取
        const formData = this.currentView.searchModel.shift();
        let hasBindCustomer = formData?.value?.hasBindCustomer
        this.hasBindCustomerText = hasBindCustomer===-1?this.$t('product.list.allProduct'):(hasBindCustomer===1?this.$t('product.list.associatedCustomer'):this.$t('product.list.unassociatedCustomer'))
        this.searchModel.hasBindCustomer = hasBindCustomer
      }else{
        this.searchModel.hasBindCustomer = -1
        this.hasBindCustomerText = this.$t('product.list.allProduct')
      }
      // this.handleAdvancedSearch(this.viewportSearchModel)
    },

    // 从视图列表 ——> 编辑、新建视图
    editViewByViewport(_v){
      const viewport = this.genViewport(_v);
      this.$refs.advancedSearchModalRef.open(viewport)
    },

    // 从高级筛选新建视图
    createViewBySearchModel(searchModel) {
      this.$refs.advancedSearchModalRef.open({ searchModel })
    },

    // 从高级筛选更新视图
    updateViewBySearchModel(searchModel) {
      const viewportData = {
        ...this.currentView,
        searchModel,
      }
      this.$refs.advancedSearchModalRef.open(viewportData)
    },

    /**
     * 视图保存成功 更新选中视图
     * @param {Object} _v 视图信息
     */
    handleViewportSave(_v){
      if(!_v) return;
      this.chooseView(_v); // 选中当前视图
      this.$refs.viewportListRef.refresh(_v.viewId); // 刷新视图列表 并选中
    },
    // 保存视图之前，存入外部固定条件到视图中
    beforeSaveView(){
      const value = {
        hasBindCustomer: this.searchModel.hasBindCustomer
      }
      return [
        {fieldName: 'productCommonSearch', operator: '', value },
      ]
    },
    /**
     * 常用字段切换
     * @param {*} fieldName
     * @param {*} isChecked
     */
    changeCommonUse({fieldName, isChecked}){
      const inCommonUseSet = new Set(this.inCommonUse)
      if(isChecked){
        inCommonUseSet.add(fieldName)
      }else {
        inCommonUseSet.delete(fieldName);
      }
      this.inCommonUse = Array.from(inCommonUseSet);
      const storageKey = 'advanced-search-commonUse';
      this.saveDataToStorage(storageKey, this.inCommonUse);
    },

    /**
     * 恢复常用字段
     */
    async recoverCommonUse(){
      try {
      const storageKey = 'advanced-search-commonUse';
        const data = await this.getLocalStorageData()
        this.inCommonUse = data[storageKey] || [];
      } catch (error) {
        console.error('获取常用字段 recoverCommonUse', error);
        return Promise.reject(error)
      }
    },
    customerLabel,
    handleCommand(command) {
      if (command == 'smartPlan') {
        if (!this.multipleSelection.length) {
          return this.$platform.alert(this.$t('common.placeholder.selectProduct'))
        }
        this.$refs.createSmartPlanDialog.open()
      } else if (command.type == 'trigger') {
        if (!this.multipleSelection.length) {
          return this.$platform.alert(this.$t('common.placeholder.selectProduct'))
        }
        this.handleManualTrigger(command.id, this.multipleSelection.map(item => item.id))
      } else if (command == 'sendMessage') {
        this.$track.clickStat(this.$track.formatParams('SEND_MESSAGE'));
        this.openDialog('sendMessage')
      } else if (command == 'sendEmail') {
        this.$track.clickStat(this.$track.formatParams('SEND_EMAIL'));
        this.openDialog('sendEmail')
      } else if (command == 'sendActivity') {
        this.$track.clickStat(this.$track.formatParams('SEND_ACTIVITY_RESEARCH'))
        this.$refs.sendActivityResearch.handleCreate()
      } else if (command == 'bindCustomer') {
        this.openDialog('bindCustomer')
      } else if (command == 'remind') {
        this.$track.clickStat(this.$track.formatParams('BATCH_REMIND'));
        this.openDialog('remind')
      } else if (command == 'edit') {
        this.$track.clickStat(this.$track.formatParams('BATCH_EDIT'));
        this.openDialog('edit')
      } else if (command == 'delete') {
        this.$track.clickStat(this.$track.formatParams('DELETE'));
        this.deleteProducts()
      }
    },
  },
  components: {
    [BatchEditingDialog.name]: BatchEditingDialog,
    [PublicDialog.name]:PublicDialog,
    [QrcodeDialog.name]:QrcodeDialog,
    [CustomerBind.name]:CustomerBind,
    [CustomizeFilterView.name]:CustomizeFilterView,
    AdvancedSearch, // 高级筛选
    AdvancedSearchModal, // 视图编辑弹框
    ViewportDropdown,
    [SendActivityResearch.name]:SendActivityResearch,
    TagsModeSelect,
  },
};
</script>
<style lang="scss" scoped>
.common-list-table {
  ::v-deep .el-table__body {
    width: 100%;
    table-layout: fixed !important;
  }
}
.unbind{
  color:#8C8C8C;
}

.task-list {
  &-header {
    background: #ffffff;
    box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.06);
    border-radius: 4px;
    margin-bottom: 12px;
    border-top: none;

    &-search {
      width: 100%;
      display: flex;
      justify-content: space-between;
      align-items: flex-start;
      // padding: 16px;
      .advanced-search-visible-btn {
        // width: 98px;
        height: 32px;
        border-radius: 4px;
        font-size: 14px;
        @include fontColor();
        line-height: 32px;
        text-align: center;
        cursor: pointer;
        white-space: nowrap;
        margin-left: 12px;
      }

      .base-search-group {
        .el-input {
          width: 400px !important;
          input {
            border-radius: 4px 0 0 4px
          }
        }
      }

      .customize-filter-view {
        margin-bottom: 16px;
      }
    }

    &-nav {
      > div {
        position: relative;
        border-top: 1px solid #f5f5f5;
        .state {
          padding-top: 4px;
          padding-left: 11px;
          width: 90px;
          font-weight: 500;
          background-color: #fafafa;
        }
        .element-icon i {
          position: absolute;
          right: 12px;
          top: 6px;
        }
        .list {
          width: 90%;
          overflow: hidden;
          // height: 30px;
          .list-item {
            > div {
              padding-left: 11px;
              font-size: 13px;
              width: 130px;
              height: 30px;
              overflow-y: hidden;
              color: #808080;
              line-height: 30px;
              cursor: pointer;
              &:hover {
                color: #333;
              }
            }
          }
        }
      }
    }
  }
}
.task-list-header-search form {
  justify-content: flex-end;
}

.import-product {
  position: relative;
  left: -15px;
  padding-left: 15px;

  &:hover &-item {
    display: block;
  }

  &-item {
    position: absolute;
    background: #fff;
    color: #333;
    left: -115px;
    top: -8px;
    border: 1px solid #eee;
    border-radius: 4px;
    display: none;
    max-height: 50vh;
    overflow-y: auto;

    >div {
      padding: 4px 15px;
      width: 120px;

      &:hover {
        background-color: $select-draggable-color;
        color: $color-primary;
      }
    }
  }
}
</style>

<style lang="scss">

html,
body {
  height: 100%;
}
.product-list-container {
  height: 100%;
  padding: 10px;
  overflow: auto;
}

.product-columns-dropdown-menu {
  max-height: 300px;
  overflow: auto;
  .el-dropdown-menu__item {
    padding: 0;
  }
  .el-checkbox {
    width: 100%;
    padding: 5px 15px;
    margin: 0;
  }
}

// search
.product-list-container .product-list-search-group-container {
  border-radius: 3px;
  .base-search {
    background: #fff;
    border-radius: 3px;
    font-size: 14px;
    display: flex;
    justify-content: space-between;
    padding: 12px 10px;

    .product-list-base-search-group {
      display: flex;
      justify-content: space-between;

      .el-input {
        width: 400px;
      }

      a {
        line-height: 33px;
      }
    }

    .advanced-search-visible-btn {
      font-size: 14px;
      line-height: 31px;
      @include fontColor();
      border-color: $color-primary;
      background: #fff;
      padding: 0 13px;
      white-space: nowrap;
      &:hover {
        cursor: pointer;
      }
    }
  }
}

.product-list-container .product-list-section {
  margin-top: 12px;
  padding-top: 0;
}

// operation
.product-list-container .product-list-section .operation-bar-container {
  background: #fff;
  border-radius: 4px 4px 0 0;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 16px 16px 0;

  .top-btn-group > * {
    margin-left: 0;
    margin-right: 12px;
    margin-bottom: 4px;
  }
  .action-button-group {
    display: flex;
    .el-dropdown, .guide-box {
      white-space: nowrap;
    }
  }

  .el-dropdown-btn {
    padding: 0 15px;
    line-height: 31px;
    display: inline-block;
    background: $color-primary-light-9;
    color: $text-color-primary;
    outline: none;
    margin-left: 5px;
    .iconfont {
      margin-left: 5px;
      // font-size: 12px;
    }

    &:hover {
      cursor: pointer;
      color: #fff;
      background: $color-primary;
    }
  }
}

// table
.el-table {
  border: none;
}
.el-table--small th,
.el-table--small td {
  height: 40px;
  padding: 3px 0;
}
.product-list-container .product-table {
  padding: 10px;

  &:before {
    height: 0;
  }

  .goods-img-list {
    height: 100%;
    img {
      width: 32px;
      height: 32px;
      margin-right: 4px;
      cursor: pointer;
    }
  }

  .product-table-header th {
    background: #f5f5f5;
    color: $text-color-primary;
    font-weight: normal;
  }

  th {
    color: #606266;
    font-size: 14px;
  }
  td {
    color: #909399;
    font-size: 13px;
  }

  .view-detail-btn {
    @include fontColor();
  }

  .view-detail-btn-disabled {
    color: #666;
    cursor: default;
  }

  .select-column .el-checkbox {
    position: relative;
    top: 3px;
  }
}

.product-list-container .table-footer {
  display: flex;
  justify-content: space-between;
  padding: 0px 10px 10px 10px;
  background: #fff;
  border-radius: 0 0 3px 3px;

  .list-info {
    font-size: 13px;
    line-height: 32px;
    margin: 0;
    color: #767e89;

    .iconfont {
      position: relative;
      top: 1px;
    }

    .product-selected-count {
      @include fontColor();
      padding: 0 3px;
      width: 15px;
      text-align: center;
      cursor: pointer;
      font-size: 13px;
    }
  }

  .el-pagination__jump {
    margin-left: 0;
  }
}

// select panel
.product-list-container .product-selected-panel {
  font-size: 14px;
  height: calc(100% - 51px);

  .product-selected-tip {
    padding-top: 80px;

    img {
      display: block;
      width: 160px;
      margin: 0 auto;
    }

    p {
      text-align: center;
      color: $text-color-regular;
      margin: 8px 0 0 0;
      line-height: 20px;
    }
  }

  .product-selected-list {
    height: 100%;
    padding: 10px;
    overflow-y: auto;

    .product-selected-row {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      border-bottom: 1px solid #ebeef5;
      font-size: 13px;

      &:hover {
        background-color: #f5f7fa;

        .product-selected-delete {
          visibility: visible;
        }
      }
    }

    .product-selected-head {
      background-color: #f0f5f5;
      color: #333;
      font-size: 14px;
    }

    .product-selected-sn {
      padding-left: 10px;
      width: 100%;
      @include text-ellipsis;
    }

    .product-selected-name {
      padding-left: 10px;
      flex: 1;
      @include text-ellipsis;
    }

    .product-selected-delete {
      width: 36px;
    }

    .product-selected-row button.product-selected-delete {
      padding: 0;
      width: 36px;
      height: 36px;
      border: none;
      background-color: transparent;
      outline: none;
      color: #646b78;
      visibility: hidden;

      i {
        font-size: 14px;
      }

      &:hover {
        color: #e84040;
      }
    }
  }
}

// advanced search form

.base-import-warn {
  p {
    margin: 0;
  }
}

// superscript
.product-name-superscript-td {
  padding: 0 !important;
  & > div {
    height: 31px;
    line-height: 31px !important;
    a {
      display: inline-block;
      height: 31px;
      line-height: 31px;
    }
  }
}

.product-panel {
  .base-panel-title {
    h3 {
      display: flex;
      justify-content: space-between;
    }
    .product-panel-btn {
      cursor: pointer;
      &:hover {
        @include fontColor();
      }
    }
  }
}
.el-table .cell {
  line-height: 31px;
}
.task-common-advanced-search-form {
  margin-bottom: 16px;

  .search-row {
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    .search-row__label {
      margin-right: 10px;
      width: 70px;
    }
    .search-row__content {
      flex: 1;
      display: flex;
      align-items: center;
    }
    .__tag {
      margin-right: 8px;
      flex: 0 0 auto;
      max-width: 180px;
      white-space: nowrap;
      text-overflow: ellipsis;
      overflow: hidden;
    }
  }
}
</style>
<style lang="scss">
  @import "@src/assets/scss/common-list.scss";
</style>
